package Cammy::Util;
use strict;
use warnings;
# VERSION
# ABSTRACT: Utility functions for Cammy

use Regexp::Common qw(URI);
use File::Spec;

use Exporter qw(import);
our @EXPORT_OK = qw(is_positive_int is_valid_filename http_client verify_config);

=head1 SYNOPSIS

    use Cammy::Util qw(is_positive_int);
    print "Give me an integer: ";
    chomp( my $input = <STDIN> );
    if ( is_positive_int($input) ) {
        print "positive!\n";
    }

=head1 DESCRIPTION

Miscellaneous utility functions for L<Cammy>.

=head1 FUNCTIONS

=cut

=head2 is_positive_int

Is this integer positive?

=cut

sub is_positive_int {
    my $val = shift;
    return defined $val && $val =~ m{^\+?\d+\z};
}

=head2 is_valid_filename

Does some basic checking on the filename to see if it is the
sort of filename we expect.

=cut

sub is_valid_filename {
    my $val = shift;
    return ($val =~ m/^\w+(?:\/\w+)*(?:.\w+)?$/);
}

=head2 http_client

Returns an appropriately-configured L<HTTP::Tiny> object.

=cut

sub http_client {
    require HTTP::Tiny;

    return HTTP::Tiny->new(
        agent   => 'Cammy/' . (defined Cammy->VERSION ? Cammy->VERSION : 'dev'),
        timeout => 10, # fail fast
    );
}

=head2 verify_config

Verifies that the configuration is correct, and applies any defaults
for omitted configuration items.

=cut

sub verify_config {
    my $config = shift;
    my $debug  = shift;

    _apply_default_config($config, $debug);
    _verify_config($config, $debug);
}

sub _verify_config {
    my $config = shift;
    my $debug  = shift;
    _verify_main_config($config, $debug);
    _verify_webcam_config($config, $debug);
}

sub _verify_main_config {
    my $config = shift;

    is_positive_int($config->{$_}) || die "$_ must be a positive integer ($config->{$_})"
        for qw(run_interval cron_interval timeout);
}

sub _verify_webcam_config {
    my $config = shift;

    # webcams
    while (my ($cam, $conf) = each %{ $config->{webcams} }) {
        is_positive_int( $conf->{$_} )
            || die "$_ for $cam must be a positive integer ($conf->{$_})"
                for qw(
                    blur_radius
                    blur_sigma
                    max_file_size_diff
                    sunset_easement
                    sunrise_easement
                    frame_rate bit_rate
        );
        $conf->{image_url} =~ $RE{URI}{HTTP}{-scheme => qr/https?/}
            or die "image_url must be a URL ($conf->{image_url})";
    }
}

sub _apply_default_config {
    my $config = shift;
    my $debug  = shift;

    _apply_default_main_config($config, $debug);
    _apply_default_webcam_config($config, $debug);
}

sub _apply_default_main_config {
    my $config = shift;

    my $default = {
        logo         => 'logo.png',
        out_dir      => File::Spec->catdir( File::Spec->rootdir, qw( var www cammy out ) ),
        run_interval => 10,
        cron_interval=> 1,
        timeout      => 8,
        interval     => 12,
    };

    $config->{$_} ||= $default->{$_}
        for keys %$default;
}

sub _apply_default_webcam_config {
    my $config = shift;

    my $default = {
        blur_radius         => 5,
        blur_sigma          => 8,
        max_file_size_diff  => 1024,
        sunset_easement     => 1,
        sunrise_easement    => 1,
        frame_rate          => 15,
        bit_rate            => 15,
        timelapse_size      => 'vga',
    };

    while (my ($cam, $conf) = each %{ $config->{webcams} }) {
        $conf->{$_} ||= $default->{$_}
            for keys %$default;
    }
}

1;
